package com.link.play.fit.ai.ui.guide


import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.View
import androidx.core.animation.doOnStart
import androidx.lifecycle.lifecycleScope
import com.link.play.fit.ai.R
import com.link.play.fit.ai.base.goToAcForResult
import com.link.play.fit.ai.bean.UserGuide
import com.link.play.fit.ai.databinding.FgPlanReady2Binding
import com.link.play.fit.ai.ext.setThrottleListener
import com.link.play.fit.ai.ui.guide.ac.GuidePbAc
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.util.Locale
import kotlin.math.roundToLong


class PlanReadyFg : BasePageFragment<FgPlanReady2Binding>(FgPlanReady2Binding::inflate) {

    private var tempData: UserGuide? = null

    @SuppressLint("SetTextI18n")
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val userGuideState = (requireActivity() as GuidePbAc).viewModel.userGuideState
        lifecycleScope.launch {
            userGuideState.collectLatest {
                when (it.gender) {
                    0 -> {
                        if (it.dataReady) {
                            maleAnimationPlay()
                        }
                    }

                    1 -> {
                        if (it.dataReady) {
                            femaleAnimationPlay()
                        }
                    }

                    2 -> {
                        if (it.dataReady) {
                            maleAnimationPlay()
                        }
                    }
                }
                if (tempData == null && it.dataReady) {
                    Log.e(TAG, "tempData=null it=$it")
                    tempData = it
                }
                if (it.imperialMetric) {
                    binding.tvTargetWeight.text = it.goalWeightKg.toString() + " kg"
                } else {
                    binding.tvTargetWeight.text = it.goalWeightLbs.toString() + " lbs"
                }

                when (it.goal) {
                    0 -> {//增重
//                        binding.tvShould.text = getString(R.string.you_should_gain)

                        binding.tvGoal.text = getString(R.string.gain_weight)
                        if (it.imperialMetric) {//公制
                            val changeW = (it.goalWeightKg - it.weightKg).toFloat()
                            val perW = it.perWeightKg
                            val date = getGoalWeightDate(changeW, perW)

//                            binding.tvGoalTime.text = "$changeW kg by $date"
                            binding.tvTitle.text = "${getString(R.string.gaining)} $changeW kg ${getString(R.string.by_text)} $date"

                        } else {//英制
                            val changeW = (it.goalWeightLbs - it.weightLbs).toFloat()
                            val perW = it.perWeightLbs
                            val date = getGoalWeightDate(changeW, perW)

//                            binding.tvGoalTime.text = "$changeW lbs by $date"
                            binding.tvTitle.text = "${getString(R.string.gaining)} $changeW lbs ${getString(R.string.by_text)} $date"
                        }
                    }

                    1 -> {//保持
                        binding.tvGoal.text = getString(R.string.hold_weight)
//                        binding.tvShould.text = getString(R.string.you_should_maintain)
                        if (it.imperialMetric) {//公制
//                            binding.tvGoalTime.text = "${it.weightKg} kg"
                        } else {//英制
//                            binding.tvGoalTime.text = "${it.weightLbs} lbs"
                        }
                        binding.tvTitle.text = getString(R.string.Maintain)
                    }

                    2 -> {//减重
                        binding.tvGoal.text = getString(R.string.lose_weight)
//                        binding.tvShould.text = getString(R.string.you_should_lose)
                        if (it.imperialMetric) {//公制

                            val changeW = (it.weightKg - it.goalWeightKg).toFloat()
                            val perW = it.perWeightKg
                            val date = getGoalWeightDate(changeW, perW)

//                            binding.tvGoalTime.text = "$changeW kg by $date"
                            binding.tvTitle.text = "${getString(R.string.losing)} $changeW kg ${getString(R.string.by_text)} $date"
                        } else {//英制

                            val changeW = (it.weightLbs - it.goalWeightLbs).toFloat()
                            val perW = it.perWeightLbs
                            val date = getGoalWeightDate(changeW, perW)

//                            binding.tvGoalTime.text = "$changeW lbs by $date"
                            binding.tvTitle.text = "${getString(R.string.losing)} $changeW lbs ${getString(R.string.by_text)} $date"
                        }
                    }
                }

                when (it.workouts) {
                    0 -> {
                        binding.tvPerAc.text = "0-2 ${getString(R.string.ready_per_week)}"
                    }

                    1 -> {
                        binding.tvPerAc.text = "3-5 ${getString(R.string.ready_per_week)}"
                    }

                    2 -> {
                        binding.tvPerAc.text = "6+ ${getString(R.string.ready_per_week)}"
                    }
                }


                if (it.caloriesDaily >= 0) {
                    binding.tvCalories.text = it.caloriesDaily.toString() + " cal"
                    binding.tvCalories2.text = it.caloriesDaily.toString()
                }
                if (it.carbsDaily >= 0) {
                    binding.tvCarbs.text = it.carbsDaily.toString()
                }
                if (it.proteinDaily >= 0) {
                    binding.tvProtein.text = it.proteinDaily.toString()
                }
                if (it.fatsDaily >= 0) {
                    binding.tvFats.text = it.fatsDaily.toString()
                }
                if (it.score != -1) {
                    binding.tvScore.text = "${it.score}/10"
                    binding.pbScore.progress = it.score
                }

            }
        }

        binding.clCal.setThrottleListener {
            lifecycleScope.launch {
                val result = requireActivity().goToAcForResult(EditPlanGoalAc::class.java) {
                    putExtra("type", TYPE_CALORIES)
                    putExtra("value", userGuideState.value.caloriesDaily.toDouble())
                }
                val value = result.data?.getDoubleExtra("result", 0.0)
                value?.let {
                    userGuideState.update { it.copy(caloriesDaily = value.toInt()) }
                }
            }
        }
        binding.clProtein.setThrottleListener {
            lifecycleScope.launch {
                val result = requireActivity().goToAcForResult(EditPlanGoalAc::class.java) {
                    putExtra("type", TYPE_PROTEIN)
                    putExtra("value", userGuideState.value.proteinDaily.toDouble())
                }
                val value = result.data?.getDoubleExtra("result", 0.0)
                value?.let { userGuideState.update { it.copy(proteinDaily = value.toInt()) } }
            }
        }
        binding.clCarbs.setThrottleListener {
            lifecycleScope.launch {
                val result = requireActivity().goToAcForResult(EditPlanGoalAc::class.java) {
                    putExtra("type", TYPE_CARBS)
                    putExtra("value", userGuideState.value.carbsDaily.toDouble())
                }
                val value = result.data?.getDoubleExtra("result", 0.0)
                value?.let { userGuideState.update { it.copy(carbsDaily = value.toInt()) } }
            }
        }
        binding.clFats.setThrottleListener {
            lifecycleScope.launch {
                val result = requireActivity().goToAcForResult(EditPlanGoalAc::class.java) {
                    putExtra("type", TYPE_FATS)
                    putExtra("value", userGuideState.value.fatsDaily.toDouble())
                }
                val value = result.data?.getDoubleExtra("result", 0.0)
                value?.let { userGuideState.update { it.copy(fatsDaily = value.toInt()) } }
            }
        }
        binding.reset.setThrottleListener {
            tempData?.let { temp ->
                userGuideState.update { temp }
            }

        }


    }


    override fun onDestroy() {
        super.onDestroy()
        tempData = null
    }

    override fun onStop() {
        super.onStop()
    }

    /**
     * 目标体重完成时间
     */
    private fun getGoalWeightDate(goalWeight: Float, perWeight: Float): String {
        val days = 7 * (goalWeight / perWeight).roundToLong()
        val date = LocalDate.now().plusDays(days)

        val formatter = DateTimeFormatter.ofPattern("MMMM dd", Locale.getDefault())
        return formatter.format(date) ?: ""
    }


    private fun maleAnimationPlay() {
        binding.ivRen.setImageResource(R.mipmap.nan_image1)

        val animatorSet = AnimatorSet()
        animatorSet.playSequentially(
            createFadeOutInAnimatorSet(R.mipmap.nan_image2),
            createFadeOutInAnimatorSet(R.mipmap.nan_image3),
            createFadeOutInAnimatorSet(R.mipmap.nan_image4),
            createFadeOutInAnimatorSet(R.mipmap.nan_image5),
        )
        animatorSet.start()
    }

    private fun femaleAnimationPlay() {
        binding.ivRen.setImageResource(R.mipmap.nv_image1)

        val animatorSet = AnimatorSet()
        animatorSet.playSequentially(
            createFadeOutInAnimatorSet(R.mipmap.nv_image2),
            createFadeOutInAnimatorSet(R.mipmap.nv_image3),
            createFadeOutInAnimatorSet(R.mipmap.nv_image4),
            createFadeOutInAnimatorSet(R.mipmap.nv_image5),
        )
        animatorSet.start()
    }

    fun createFadeOutInAnimatorSet(fadeInRes: Int): AnimatorSet {
        val fadeOut = ObjectAnimator.ofFloat(binding.ivRen, "alpha", 1f, 0.9f).apply {
            duration = 100
        }
        val fadeIn = ObjectAnimator.ofFloat(binding.ivRen, "alpha", 0.9f, 1f).apply {
            duration = 100
        }
        fadeIn.doOnStart {
            binding.ivRen.setImageResource(fadeInRes)
        }
        val animatorSet = AnimatorSet()
        animatorSet.play(fadeIn).after(fadeOut)

        return animatorSet
    }

}